import Foundation

protocol MPConvertibleArray {
    static func mp_subType() -> Any.Type
}

extension NSArray: MPConvertibleArray {
    
    static func mp_subType() -> Any.Type {
        if let optionType = self.Element as? MPConvertibleOptional.Type {
            return optionType.mp_subType()
        }
        return self.Element
    }
    
}

extension Array: MPConvertibleArray {
    
    static func mp_subType() -> Any.Type {
        if let optionType = self.Element as? MPConvertibleOptional.Type {
            return optionType.mp_subType()
        }
        return self.Element
    }
    
}

func mp_array_value(_ value: Any, type: Any.Type?) -> [Any]? {
    guard let array = value as? [Any] ?? (value as? MPConvertibleSet)?.mp_to_array() else { return nil }
    if let subType = type as? MPConvertible.Type {
        return array.compactMap {
            if let dic = mp_valueToDic($0) {
                return subType.mp_model(dic)
            }
            return nil
        }
    }
    if let subType = type as? any RawRepresentable.Type {
        return array.compactMap {
            return subType.mp_enum($0)
        }
    }
    if let subType = type as? MPConvertibleDictionary.Type {
        return array.compactMap {
            return mp_dict_value($0,type:subType)
        }
    }
    if let subType = type as? MPConvertibleArray.Type {
        return array.compactMap {
            return mp_array_value($0, type:subType)
        }
    }
    return array
}

func mp_array(_ value: Any, type: Any.Type?, subType: Any.Type?) -> MPConvertibleArray? {
    guard let array = mp_array_value(value, type: subType) else { return nil }
    return type is NSMutableArray.Type ? NSMutableArray.init(array: array) : array
}

func mp_arrayToStr(_ array: [Any]) ->String? {
    if let data = try? JSONSerialization.data(withJSONObject: array, options: []) {
        return String.init(data: data, encoding: .utf8)
    }
    return nil
}
